#include "mainwidget.h"
#include "mainwindow.h"
#include "friendslist.h"
#include "friendsitem.h"
#include "chatwindow.h"

#include <QComboBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSizePolicy>
#include <QPushButton>
#include <QTimer>
#include <QIcon>
#include <QLineEdit>
#include <QInputDialog>
#include <QMessageBox>

#include "common/chat.h"

#include <iostream>

namespace Ui {

MainWidget::MainWidget(quint16 inactivityTime, QWidget *parent) : QWidget(parent) , inactivityTime(inactivityTime) {

	friendsList= new FriendsList(this);
	connect(friendsList,SIGNAL(startChat(int)),this,SIGNAL(startChat(int)));

	statusCombo= new QComboBox();
	statusCombo->addItem(QIcon("data/img/online.png"),"Online");
	statusCombo->addItem(QIcon("data/img/away.png"),"Away");
	statusCombo->addItem(QIcon("data/img/inactivity.png"),"Inactivity Away");
	statusCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));

	connect(statusCombo,SIGNAL(currentIndexChanged(int)),this,SLOT(statusChanged(int)));

	addIcon = new QPushButton(QIcon("data/img/add.png"),"");
	connect(addIcon, SIGNAL(clicked()), this, SLOT(inviteFriend()));

	removeIcon = new QPushButton(QIcon("data/img/remove.png"),"");
	connect(removeIcon, SIGNAL(clicked()), this, SLOT(removeFriend()));


	statusLayout = new QHBoxLayout();
	statusLayout->addWidget(statusCombo);
	statusLayout->addWidget(addIcon);
	statusLayout->addWidget(removeIcon);

	mainLayout = new QVBoxLayout();
	mainLayout->addWidget(friendsList);
	mainLayout->addLayout(statusLayout);

	setLayout(mainLayout);
	friendsList->show();
	statusCombo->show();
	
	inactivity = 	new QTimer(this);
	connect(inactivity,SIGNAL(timeout()),this,SLOT(awayInactivity()));
	if(inactivityTime != 0) inactivity->start(inactivityTime);

	connect(this,SIGNAL(newOutcomingMessage(const QString &, Chat *)),this,SLOT(restartInactivityCountdown()));
	connect(this,SIGNAL(statusChanged(Status)),this,SLOT(restartInactivityCountdown()));

}

Friend *MainWidget::getMe(){
	return me;
}

void MainWidget::setMe(Friend *me){
	this->me=me;
}

void MainWidget::setInactivityTime(quint16 inactivityTime) {
	this->inactivityTime = inactivityTime;
	restartInactivityCountdown();
}

void MainWidget::statusChanged(int _index) {
	switch(_index) {
		case 0:
			emit statusChanged(Online);
			restartInactivityCountdown();
			break;
		case 1:
			emit statusChanged(Away);
			break;
		case 2:
			emit statusChanged(Inactivity);
			break;
	}		
}

void MainWidget::friendStatusChanged(Friend *_friend, QList<int> _chats) {
	static_cast<MainWindow *>(parent())->friendChangedStatusMessage(_friend->getName(),_friend->getStatus());

	/* Updating friendsList */
	friendsList->updateFriend(_friend);
	/* Updating each ChatWindow */
	foreach(int id, _chats) {
		ChatWindow* chatWindow = chats[id];
		if(chatWindow) {
			chatWindow->updateStatusFriend(_friend);
		}
	}
}
void MainWidget::loadFriends(QList<Friend *> friends){
	friendsList->loadFriends(friends);
}

void MainWidget::newMessageIncoming(Chat* chat, Friend* _friend, const QString& _text) {
	ChatWindow* chatWindow = chats[chat->getId()] ;
	if(chatWindow) chatWindow->newIncomingMessage(_friend, _text);
}

void MainWidget::newChatWindow(Chat* chat) {
	ChatWindow * chatWindow= new ChatWindow(chat, me, this);
	connect(chatWindow,SIGNAL(newOutcomingMessage(const QString&, Chat *)),this,SIGNAL(newOutcomingMessage(const QString&, Chat *)));
	connect(chatWindow, SIGNAL(inviteChat(Chat*, QString)), this, SLOT(inviteChatId(Chat*, QString)));
	connect(chatWindow, SIGNAL(quitChat(Chat *)), this, SIGNAL(quitChat(Chat *)));
	chats[chat->getId()] = chatWindow;
	chatWindow->show();
}

void MainWidget::friendExit(Chat* chat, Friend* _friend){
	Friend *myFriend = friendsList->getFriend(_friend->getId());
	ChatWindow* chatWindow = chats[chat->getId()] ;
	if(chatWindow) chatWindow->removeFriend(myFriend);
}

void MainWidget::chatTerminated(Chat* chat){
	ChatWindow* chatWindow = chats[chat->getId()] ;
	chatWindow->terminate();
}

void MainWidget::newFriendChat(Chat* _chat, Friend* _friend) {
	ChatWindow* chatWindow = chats[_chat->getId()];
	if(chatWindow) chatWindow->addFriend(_friend);
}

void MainWidget::inviteChatId(Chat* chat, QString login) {
	int id = friendsList->getId(login);
	emit inviteChat(chat, id);
}

void MainWidget::inviteFriend() {
	bool ok;
	QString text = QInputDialog::getText(this, tr("Invite Friend"), tr("Login:"), QLineEdit::Normal, "", &ok);
	if(ok && !text.isEmpty()) {
		QMessageBox::information(this, "Invitation", "Your invitation will be processed as soon as possible");
		emit inviteFriend(text);
	}
}

void MainWidget::removeFriend() {
	if(friendsList->selectedItems().size()>0){
			QTreeWidgetItem *item = *(friendsList->selectedItems().begin());
			if(friendsList->indexOfTopLevelItem(item)==-1) {
				Friend *friend_ = static_cast<FriendsItem *>(item)->getFriend();
				if(QMessageBox::question(this, "Remove friend", "Are you sure you want to remove " + friend_->getName() + "?",QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
					emit removeFriend(friend_);
				}
			}
	}
}

void MainWidget::friendInvitation(const QString &login) {
	if(QMessageBox::question(this, "Friend Invitation", "User " + login + " invited you to be his friend. Do you want to accept the invitation?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
		emit acceptInvitation(login);
	}
	else {
		emit denyInvitation(login);
	}
}

void MainWidget::friendAddition(Friend *_friend) {
	QMessageBox::information(this, "Friend Addition", "You are now friend of " + _friend->getName() + ".", QMessageBox::Ok);
	friendsList->addFriend(_friend);
}

void MainWidget::friendDenial(const QString &login) {
	QMessageBox::information(this, "Friend Denial", "User " + login + " denied your invitation to be his friend.", QMessageBox::Ok);
}

void MainWidget::friendRemoval(Friend *_friend, QList<int> chats) {
	QMessageBox::information(this, "Friend Removal", "User " + _friend->getName() + " has been removed from his friends list.", QMessageBox::Ok);
	foreach(int id, chats) {
		this->chats[id]->removeFriend(_friend);
	}
	delete friendsList->getFriend(_friend->getId());
	friendsList->removeFriend(_friend->getId());
}

void MainWidget::awayInactivity() {
	statusChanged(2);
	statusCombo->setCurrentIndex(2);
	inactivity->stop();
}
void MainWidget::restartInactivityCountdown() {
	inactivity->stop();
	if(inactivityTime != 0) inactivity->start(inactivityTime);
}
}

